#ifndef __LEARNDX_RENDER_DRIVER_D3D11_H_INCLUDE__
#define __LEARNDX_RENDER_DRIVER_D3D11_H_INCLUDE__
#include "LDXConfig.h"
#include "IRenderDriver.h"
#include "SDeviceMap.h"
#include "DCBufferDefines.h"
#include "CRenderStateConsole.h"

namespace ldx
{
	namespace render
	{
		class CTexture;
		class CShaderManager;
		class CTexturesCache;
		//! The driver for d3d11
		/** 
		* Main functions are:
			swapChain(),
			clear(E_CLEAR_FLAG flag,SColorf& color )
		*/
		class CRenderDriverD3D11 final :public IRenderDriver
		{
		public:

			CRenderDriverD3D11(device::WinDevice* device, HWND hwnd,mt::dimension2du screensize,uint bits,bool fullscreen,bool depthbuffer,bool stencilbuffer);

			virtual ~CRenderDriverD3D11();
			
			virtual bool clear(E_CLEAR_FLAG flag,SColorf& color ,float depth = 1.0f,uint stencil = 0) override;

			virtual bool clearColorBuffer(SColorf& color = SColorf(1.f, 1.f, 1.f, 1.f)) override;

			virtual bool clearDepthBuffer(float depth = 1.0f) override;

			virtual bool clearStencilBuffer(uint stentil = 0) override;

			virtual bool swapChain() override;

			virtual void setTransform(E_TRANFORM_MATRIX transform, mt::mat4& matrix)override;

			virtual mt::mat4& getTransform(E_TRANFORM_MATRIX transform) override;

			virtual void setViewPosition(const mt::vec3f& pos)override;

			virtual mt::vec3f& getViewPosition()override;

			virtual void setViewDirection(const mt::vec3f& dir)override;

			virtual mt::vec3f& getViewDirection()override;

			virtual mt::vector2dui getScreenSize() override;

			virtual mt::vector2di getCurrentRenderTargetSize() override;

			SDeviceMap getDeviceMap();

			virtual CShaderManager* getShaderManager()override;
			
			virtual CTexturesCache* getTexturesCache()override;
			
			//! add texture
			virtual CTexture* addTexture(std::string& pathName)override;


			virtual int setRasterState(E_RASTER_STATE_TYPES rasterstate)override;

			//! ori: top-left
			virtual int serRasterViewPort(float width, float height, float topleftX = 0.f, float topleftY = 0.f, float depthmin = 0.f, float depthmax = 1.0f)override;

			virtual SViewPort getRasterViewPort()override;

		private:
			
			long initD3D11();

			long initShaders();

			//! init texture cache,mesh cache
			long initCaches();

			void deleteD3D11();

			//! Caches
			CTexturesCache* TexturesCache;

			uint Bits = 24;
			bool IsDepthBuffer = true;
			bool IsStencilBuffer = true;
			bool IsFullScreen = false;
			mt::dimension2du ScreenSize;

			device::WinDevice* Device;//ref

			// hold
			CShaderManager* ShaderManager;
			CRenderStateConsole* RenderConsole;//console for raster ,depth stencil,blend

			HINSTANCE               HInst = NULL;
			HWND                    HWnd = NULL;
			D3D_DRIVER_TYPE         DriverType = D3D_DRIVER_TYPE_NULL;
			D3D_FEATURE_LEVEL       FeatureLevel = D3D_FEATURE_LEVEL_11_0;
			ID3D11Device*           Pd3dDevice = NULL;
			ID3D11DeviceContext*    PImmediateContext = NULL;
			IDXGISwapChain*         PSwapChain = NULL;
			ID3D11RenderTargetView* PRenderTargetView = NULL;
			ID3D11Texture2D*	    PDepthStencil = NULL;//
			ID3D11DepthStencilView* PDepthStencilView = NULL;//
			
			mt::mat4 TransformMatrix[ETM_TRANSFORM_COUNT];
			mt::vec3f CameraPosition;
			mt::vec3f CameraDirection;
		};

	}
}

#endif//! __LEARNDX_RENDER_DRIVER_D3D11_H_INCLUDE__